package cn.tonyandmoney.voicenotes.ui.activity

import android.os.Bundle
import android.view.*
import android.widget.EditText
import android.widget.LinearLayout
import android.widget.TextView
import cn.tonyandmoney.baidu.bus.SpeechBus
import cn.tonyandmoney.baidu.consumers.RxConsumer
import cn.tonyandmoney.baidu.tts.event.SpeakEvent
import cn.tonyandmoney.voicenotes.R
import cn.tonyandmoney.voicenotes.greendao.gen.NoteRecordDao
import cn.tonyandmoney.voicenotes.greendao.gen.TRecordDao
import cn.tonyandmoney.voicenotes.greendao.utils.GreenDaoHelper
import cn.tonyandmoney.voicenotes.notes.entity.TNote
import cn.tonyandmoney.voicenotes.notes.model.NoteDetailsModel
import cn.tonyandmoney.voicenotes.wav.ui.AudioPlayerActivity
import com.afollestad.materialdialogs.MaterialDialog
import com.dhh.rxlifecycle2.RxLifecycle
import com.zlzsy.app.base.ui.BaseActivity
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import org.jetbrains.anko.*
import org.jetbrains.anko.recyclerview.v7.recyclerView
import org.jetbrains.anko.sdk25.coroutines.onClick
import org.jetbrains.anko.sdk25.coroutines.textChangedListener

/**
 * 笔记详情
 */
class NoteDetailsActivity : BaseActivity(), Consumer<SpeakEvent> {

    private val nTag = "note_tag_"
    private lateinit var mEditMenu: MenuItem
    private lateinit var mSaveMenu: MenuItem
    private lateinit var mLayout: LinearLayout
    private val mModel = NoteDetailsModel()
    private lateinit var mNote: TNote

    override fun initView() {
        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        verticalLayout {
            mLayout = this
            themedLinearLayout(R.style.Normal_LinearLayout) {
                themedTextView(R.style.TextView_ItemTitle) {
                    text = "名称："
                }
                themedEditText(R.style.TextView_ItemEditView) {
                    tag = nTag + "name"
                    lines = 1
                    isEnabled = false
                    textChangedListener {
                        onTextChanged { text, _, _, _ ->
                            updateNote(tag as String, text?.toString() ?: "")
                        }
                    }
                }.lparams(matchParent, wrapContent)
            }.lparams(matchParent, wrapContent)
            themedLinearLayout(R.style.Normal_LinearLayout) {
                themedTextView(R.style.TextView_ItemTitle) {
                    text = "分类："
                }
                themedEditText(R.style.TextView_ItemEditView) {
                    tag = nTag + "type"
                    lines = 1
                    isEnabled = false
                    textChangedListener {
                        onTextChanged { text, _, _, _ ->
                            updateNote(tag as String, text?.toString() ?: "")
                        }
                    }
                }.lparams(matchParent, wrapContent)
            }.lparams(matchParent, wrapContent)
            themedLinearLayout(R.style.Normal_LinearLayout) {
                themedTextView(R.style.TextView_ItemTitle) {
                    text = "备注："
                }
                themedEditText(R.style.TextView_ItemEditView) {
                    tag = nTag + "memo"
                    maxHeight = dip(80)
                    isEnabled = false
                    textChangedListener {
                        onTextChanged { text, _, _, _ ->
                            updateNote(tag as String, text?.toString() ?: "")
                        }
                    }
                }.lparams(matchParent, wrapContent)
            }.lparams(matchParent, wrapContent)
            themedLinearLayout(R.style.Normal_LinearLayout) {
                themedTextView(R.style.TextView_ItemTitle) {
                    text = "内容："
                }
                scrollView {
                    themedEditText(R.style.TextView_ItemEditView) {
                        tag = nTag + "content"
                        isEnabled = false
                        textChangedListener {
                            onTextChanged { text, _, _, _ ->
                                updateNote(tag as String, text?.toString() ?: "")
                            }
                        }
                    }.lparams(matchParent, wrapContent)
                }.lparams(matchParent, dip(120))
            }.lparams(matchParent, wrapContent)
            recyclerView {

            }.lparams(matchParent, 0, 1f)
            linearLayout {
                textView {
                    id = R.id.btn_b
                    backgroundResource = R.drawable.btn_round_corner
                    gravity = Gravity.CENTER
                    text = "自动朗读"
                    textSize = 18f
                    textColor = resources.getColor(android.R.color.white)
                    onClick { speak() }
                }.lparams(0, matchParent, 1f)
                textView {
                    id = R.id.btn_b
                    backgroundResource = R.drawable.btn_round_corner
                    gravity = Gravity.CENTER
                    text = "查看文件"
                    textSize = 18f
                    textColor = resources.getColor(android.R.color.white)
                    onClick { allFiles() }
                }.lparams(0, matchParent, 1f)
            }.lparams(matchParent, dip(45))
        }
    }

    override fun initData(savedInstanceState: Bundle?) {
        val noteId = intent.getLongExtra("noteId", -1L)
        if (noteId < 0) {
            longToast("系统错误。")
            finish()
            return
        }
        mNote = mModel.loadById(noteId)
        update(find(android.R.id.content))
        SpeechBus.register<SpeakEvent>()
                .compose(RxLifecycle.with(this).bindOnDestroy())
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(RxConsumer(this))
    }

    /**
     * 自定播放该笔记的内容
     */
    private fun speak() {
        find<View>(R.id.btn_b).isEnabled = false
        val speakEvent = SpeakEvent(SpeakEvent.CODE_SPEAK)
        speakEvent.id = mNote.id.toString()
        speakEvent.message = "名称：${mNote.name}"
        SpeechBus.post(speakEvent)
        speakEvent.message = "类型：${mNote.type ?: "无"}"
        SpeechBus.post(speakEvent)
        speakEvent.message = "备注：${mNote.memo ?: "无"}"
        SpeechBus.post(speakEvent)
        speakEvent.message = "内容：${mNote.content ?: "无"}"
        SpeechBus.post(speakEvent)
        speakEvent.message = "朗读完成"
        speakEvent.id += "END"
        SpeechBus.post(speakEvent)
    }

    override fun accept(t: SpeakEvent) {
        if ((t.code == SpeakEvent.CODE_FINISH || t.code == SpeakEvent.CODE_ERROR)) {
            find<View>(R.id.btn_b).isEnabled = true
        }
    }


    /**
     * 查看该笔记的所有文件
     */
    private fun allFiles() {
        val fileDao = GreenDaoHelper.session().noteRecordDao
        val list = fileDao.queryBuilder()
                .where(NoteRecordDao.Properties.NoteId.eq(mNote.id))
                .list()
                .map { it.recordId }

        val fileList = GreenDaoHelper.session().tRecordDao
                .queryBuilder()
                .where(TRecordDao.Properties.Id.`in`(list))
                .list()

        MaterialDialog.Builder(this)
                .title("文件列表")
                .items(fileList.map { it.fileName })
                .itemsCallback { _, _, position, _ ->
                    if (position < 0 && position >= fileList.size) return@itemsCallback
                    val file = fileList[position]
                    startActivity<AudioPlayerActivity>("id" to file.id)
                }
                .autoDismiss(false)
                .negativeText(R.string.cancel)
                .onNegative { dialog, _ ->
                    dialog.dismiss()
                }
                .show()


    }


    /**
     * 更新Note 的数据，
     */
    private fun update(viewGroup: ViewGroup) {
        Observable.range(0, viewGroup.childCount)
                .map { viewGroup.getChildAt(it) }
                .subscribe {
                    if (it is ViewGroup)
                        update(it)
                    else if (it is TextView) {
                        updateView(it)
                    }
                }
    }

    @Throws(Exception::class)
    private fun updateView(textView: TextView) {
        val tag = textView.tag?.toString() ?: return
        if (!tag.startsWith(nTag)) return
        val fieldName = tag.replace(nTag, "")
        val field = TNote::class.java.getDeclaredField(fieldName) ?: return
        field.isAccessible = true
        val fieldValue = field.get(mNote)
        if (fieldValue != null) {
            textView.text = fieldValue as String
        }
    }

    @Throws(Exception::class)
    private fun updateNote(tag: String, text: String) {
        if (!tag.startsWith(nTag)) return
        val fieldName = tag.replace(nTag, "")
        val field = TNote::class.java.getDeclaredField(fieldName) ?: return
        field.isAccessible = true
        field.set(mNote, text)
    }

    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.note_details_menu, menu)
        mEditMenu = menu.findItem(R.id.action_edit)
        mSaveMenu = menu.findItem(R.id.action_save)
        return true
    }


    private fun saveNote() {
        showLoadingDialog("正在保存...")
        Observable.create<Int> {
            mModel.saveNote(mNote)
            it.onNext(0);it.onComplete()
        }.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    hideLoadingDialog()
                    mSaveMenu.isVisible = false
                    mEditMenu.isVisible = true
                    changeToEdit(false, mLayout)
                }
    }

    private fun changeToEdit(enable: Boolean, viewGroup: ViewGroup) {
        Observable.range(0, viewGroup.childCount)
                .map { viewGroup.getChildAt(it) }
                .subscribe {
                    if (it is ViewGroup) {
                        changeToEdit(enable, it)
                    } else if (it is EditText) {
                        it.isEnabled = enable
                    }
                }
    }


    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.action_edit) {
            changeToEdit(true, mLayout)
            mEditMenu.isVisible = false
            mSaveMenu.isVisible = true
            return true
        } else if (item.itemId == R.id.action_save) {
            saveNote()
            return true
        }
        return super.onOptionsItemSelected(item)
    }


}